package com.ruowei.modules.sys.utils;


import com.ruowei.modules.sys.pojo.TimeAO;

import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;

/**
 * 年份周次相关工具类
 *
 * @author 董兴
 * @date 2019年8月22日
 */
public class WeekOfYearUtils {

    /**
     * 获取当前季度
     */
    public static Integer getQuarter() {
        Calendar c = Calendar.getInstance();
        int month = c.get(Calendar.MONTH) + 1;
        int quarter = 0;
        if (month <= 3) {
            quarter = 1;
        } else if (month <= 6) {
            quarter = 2;
        } else if (month <= 9) {
            quarter = 3;
        } else {
            quarter = 4;
        }
        return quarter;
    }

    public static Instant getQuarterStartBy(Integer year, Integer num) {
        switch (num) {
            case 1: {
                //第一季度
                return getMonthStartBy(year, 1);
            }
            case 2: {
                //第二季度
                return getMonthStartBy(year, 4);
            }
            case 3: {
                //第三季度
                return getMonthStartBy(year, 7);
            }
            case 4: {
                //第四季度
                return getMonthStartBy(year, 10);
            }
        }
        return null;
    }

    public static Instant getQuarterEndBy(Integer year, Integer num) {
        switch (num) {
            case 1: {
                //第一季度
                return getMonthEndBy(year, 3);
            }
            case 2: {
                //第二季度
                return getMonthEndBy(year, 6);
            }
            case 3: {
                //第三季度
                return getMonthEndBy(year, 9);
            }
            case 4: {
                //第四季度
                return getMonthEndBy(year, 12);
            }
        }
        return null;
    }

    public static List<String> getMonthPasts(Integer past) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < past; i++) {
            list.add(getMonthPast(i));
        }
        return list;
    }

    public static String getMonthPast(Integer month) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -month);
        return format.format(calendar.getTime());
    }

    /**
     * 获取本月开始日期
     *
     * @return String
     **/
    public static Instant getMonthStart() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date time = cal.getTime();
        LocalDate localDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(time));
        LocalTime localTime = LocalTime.of(0, 0, 0);
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    public static Instant getDayStart() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        Date time = cal.getTime();
        LocalDate localDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(time));
        LocalTime localTime = LocalTime.of(0, 0, 0);
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    public static Instant getDayEnd() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        Date time = cal.getTime();
        LocalDate localDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(time));
        LocalTime localTime = LocalTime.of(23, 59, 59);
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    public static Instant getDayStartBy(LocalDate tmp) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(DateConvertUtils.localdateToDate(tmp));
        cal.set(Calendar.HOUR, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        Date time = cal.getTime();
        LocalDate localDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(time));
        LocalTime localTime = LocalTime.of(0, 0, 0);
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    public static Instant getDayEndBy(LocalDate tmp) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(DateConvertUtils.localdateToDate(tmp));
        cal.set(Calendar.HOUR, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        Date time = cal.getTime();
        LocalDate localDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(time));
        LocalTime localTime = LocalTime.of(23, 59, 59);
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    /**
     * 获取本月最后一天
     *
     * @return String
     **/
    public static Instant getMonthEnd() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date time = cal.getTime();
        LocalDate localDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(time));
        LocalTime localTime = LocalTime.of(23, 59, 59);
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    /**
     * @param month 1-12
     * @apiNote 获取某月第一天日期
     * @author 董兴
     * @date 2020-04-21
     */
    public static Instant getMonthStartBy(Integer year, Integer month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date time = cal.getTime();
        LocalDate localDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(time));
        LocalTime localTime = LocalTime.of(0, 0, 0);
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    public static Instant getYearStartBy(Integer year) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        Date time = calendar.getTime();
        LocalDate localDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(time));
        LocalTime localTime = LocalTime.of(0, 0, 0);
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    public static Instant getYearEndBy(Integer year) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, 11);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date time = calendar.getTime();
        LocalDate localDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(time));
        LocalTime localTime = LocalTime.of(0, 0, 0);
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    /**
     * @param month
     * @apiNote 获取某月最后一天日期
     * @author 董兴
     * @date 2020-04-21
     */
    public static Instant getMonthEndBy(Integer year, Integer month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date time = cal.getTime();
        LocalDate localDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(time));
        LocalTime localTime = LocalTime.of(23, 59, 59);
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    /**
     * 根据当前日期获取年份,下周周次以及周开始结束时间
     *
     * @return
     * @author 董兴
     */
    public static TimeAO huoquxiazhou() {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置周一为一周开始的第一天
        int year = calendar.get(Calendar.YEAR);//获得年份
        int week = calendar.get(Calendar.WEEK_OF_YEAR);//当前周次
        int nextWeek = week + 1;//下周周次

        if (week == 52) {
            year += 1;
            nextWeek = 1;
        }
        calendar.setWeekDate(year, nextWeek, Calendar.MONDAY);//获得周一的时间
        LocalDate startTime = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

        calendar.setWeekDate(year, nextWeek, Calendar.SUNDAY);//获得周日的时间
        LocalDate endTime = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        TimeAO timeAO = new TimeAO();
        timeAO.setNianfen(String.valueOf(year));
        timeAO.setZhouci(nextWeek);
        timeAO.setStartTime(startTime);
        timeAO.setEndTime(endTime);
        return timeAO;
    }

    /**
     * 根据当前日期获取年份,本周周次以及周开始结束时间
     *
     * @return
     * @author 董兴
     */
    public static TimeAO huoqubenzhou() {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置周一为一周开始的第一天
        int year = calendar.get(Calendar.YEAR);//获得年份
        int month = calendar.get(Calendar.MONTH);//获得月份
        int week = calendar.get(Calendar.WEEK_OF_YEAR);//当前周次
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        calendar.setWeekDate(year, week, Calendar.MONDAY);//获得周一的时间
        LocalDate startTime = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

        calendar.setWeekDate(year, week, Calendar.SUNDAY);//获得周日的时间
        LocalDate endTime = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        TimeAO timeAO = new TimeAO();
        timeAO.setNianfen(String.valueOf(year));
        timeAO.setYuefen(month);
        timeAO.setZhouci(week);
        timeAO.setZhouji(day);
        timeAO.setStartTime(startTime);
        timeAO.setEndTime(endTime);
        return timeAO;
    }

    /**
     * 根据当前日期获取年份,上周周次以及周开始结束时间
     *
     * @return
     * @author 董兴
     */
    public static TimeAO huoqushangzhou() {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置周一为一周开始的第一天
        int year = calendar.get(Calendar.YEAR);//获得年份
        int week = calendar.get(Calendar.WEEK_OF_YEAR);//当前周次
        int lastWeek = week - 1;
        if (week == 1) {
            lastWeek = 52;
            year -= 1;
        }
        calendar.setWeekDate(year, lastWeek, Calendar.MONDAY);//获得周一的时间
        LocalDate startTime = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

        calendar.setWeekDate(year, lastWeek, Calendar.SUNDAY);//获得周日的时间
        LocalDate endTime = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        TimeAO timeAO = new TimeAO();
        timeAO.setNianfen(String.valueOf(year));
        timeAO.setZhouci(lastWeek);
        timeAO.setStartTime(startTime);
        timeAO.setEndTime(endTime);
        return timeAO;
    }

    /**
     * 根据指定日期获取年份,当前周次以及周开始结束时间
     *
     * @return
     * @author 董兴
     */
    public static TimeAO huoquzhouciByRiqi(LocalDate localDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置周一为一周开始的第一天
        calendar.setMinimalDaysInFirstWeek(4);
        calendar.setTime(DateConvertUtils.localdateToDate(localDate));
        int year = calendar.get(Calendar.YEAR);//获得年份
        int week = calendar.get(Calendar.WEEK_OF_YEAR);//当前周次
        calendar.setWeekDate(year, week, Calendar.MONDAY);//获得周一的时间
        LocalDate startTime = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

        calendar.setWeekDate(year, week, Calendar.SUNDAY);//获得周日的时间
        LocalDate endTime = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        TimeAO timeAO = new TimeAO();
        timeAO.setNianfen(String.valueOf(year));
        timeAO.setZhouci(week);
        timeAO.setStartTime(startTime);
        timeAO.setEndTime(endTime);
        return timeAO;
    }

    /**
     * @param nianfen
     * @param zhouci
     * @apiNote 根据年份周次获取年份, 当前周次以及周开始结束时间
     * @author 董兴
     * @date 2020-01-07
     */
    public static TimeAO huoquzhouciByNianfenZhouci(Integer nianfen, Integer zhouci) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        calendar.set(Calendar.YEAR, nianfen);
        calendar.set(Calendar.WEEK_OF_YEAR, zhouci);
        calendar.setMinimalDaysInFirstWeek(4);
        calendar.setWeekDate(nianfen, zhouci, Calendar.MONDAY);
        LocalDate startTime = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

        calendar.setWeekDate(nianfen, zhouci, Calendar.SUNDAY);
        LocalDate endTime = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        TimeAO timeAO = new TimeAO();
        timeAO.setNianfen(String.valueOf(nianfen));
        timeAO.setZhouci(zhouci);
        timeAO.setStartTime(startTime);
        timeAO.setEndTime(endTime);
        return timeAO;
    }

    /**
     * 根据年份周次获取日期范围
     *
     * @param nianfen
     * @param zhouci
     * @return
     * @author 董兴
     * @date 2019年8月26日
     */
    public static Map<String, LocalDate> huoquriqiByzhouci(String nianfen, Integer zhouci) {
        Map<String, LocalDate> map = new HashMap<>();

        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setWeekDate(Integer.valueOf(nianfen), zhouci, Calendar.MONDAY);
        map.put("start", calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());

        calendar.setWeekDate(Integer.valueOf(nianfen), zhouci, Calendar.SUNDAY);
        map.put("end", calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
        return map;
    }

    /**
     * @param nianfen
     * @param zhouci
     * @apiNote 根据年份周次 获取周一日期
     * @author 董兴
     * @date 2020-01-07
     */
    public static Date huoquzhouyiByZhouci(String nianfen, Integer zhouci) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setWeekDate(Integer.valueOf(nianfen), zhouci, Calendar.MONDAY);
        return calendar.getTime();
    }

    /**
     * @param intervals 过去几天
     * @apiNote 获取过去几天的日期, 不带今天的
     * @author 董兴
     * @date 2019-10-17
     */
    public static List<String> getPastDate(int intervals) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < intervals; i++) {
            list.add(getPast(i));
        }
        return list;
    }

    /**
     * @param past 过去第几天
     * @apiNote 获取过去某一天的日期
     * @author 董兴
     * @date 2019-10-17
     */
    public static String getPast(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
        Date today = calendar.getTime();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        return formatter.format(today);
    }

    public static List<String> getFutureDate(int intervals) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < intervals; i++) {
            list.add(getFuture(i + 1));
        }
        return list;
    }

    public static String getFuture(int future) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + future);
        Date today = calendar.getTime();
        SimpleDateFormat formatter = new SimpleDateFormat("MM-dd");
        return formatter.format(today);
    }

    /**
     * @param nianfen 年份
     * @param zhouci  周次
     * @param zhouji  周几
     * @apiNote 根据年份周次和周几获取日期
     * @author 董兴
     * @date 2019-11-14
     */
    public static LocalDate getLocalDateFrom(Integer nianfen, Integer zhouci, String zhouji) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.YEAR, nianfen);
        calendar.set(Calendar.WEEK_OF_YEAR, zhouci);
        switch (zhouji) {
            case "周一": {
                calendar.set(Calendar.DAY_OF_WEEK, 2);
                break;
            }
            case "周二": {
                calendar.set(Calendar.DAY_OF_WEEK, 3);
                break;
            }
            case "周三": {
                calendar.set(Calendar.DAY_OF_WEEK, 4);
                break;
            }
            case "周四": {
                calendar.set(Calendar.DAY_OF_WEEK, 5);
                break;
            }
            case "周五": {
                calendar.set(Calendar.DAY_OF_WEEK, 6);
                break;
            }
            case "周六": {
                calendar.set(Calendar.DAY_OF_WEEK, 7);
                break;
            }
            case "周日": {
                calendar.set(Calendar.DAY_OF_WEEK, 1);
                break;
            }
        }
        Date date = calendar.getTime();
        return DateConvertUtils.dateToLocalDate(date);
    }

    public static Boolean isFirstDayOfMonth(Calendar calendar) {
        return calendar.get(Calendar.DAY_OF_MONTH) == 1;
    }

    public static Boolean isLastDayOfMonth(Calendar calendar) {
        return calendar.get(Calendar.DAY_OF_MONTH) == calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    public static TimeAO getstartandlastByNianfenAndYuefen(Integer nianfen, Integer yuefen) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        // 不加下面2行，就是取当前时间前一个月的第一天及最后一天
        cal.set(Calendar.YEAR, nianfen);
        cal.set(Calendar.MONTH, yuefen);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.DAY_OF_MONTH, -1);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);

        Date lastDate = cal.getTime();
//        System.out.println(format.format(lastDate));
//        LocalDate endTime = cal.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        Date firstDate = cal.getTime();
//        System.out.println(format.format(firstDate));
//        LocalDate startTime = cal.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();


        TimeAO timeAO = new TimeAO();
        timeAO.setStartTimelingdian(format.format(firstDate));
        timeAO.setEndTimezhongdian(format.format(lastDate));
        return timeAO;
    }

    public static TimeAO getstartandlastDangqian() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal1 = Calendar.getInstance();
        // 不加下面2行，就是取当前时间前一个月的第一天及最后一天
        cal1.add(Calendar.MONTH, 0);
        cal1.set(Calendar.DAY_OF_MONTH, 1);
        cal1.set(Calendar.HOUR_OF_DAY, 0);
        cal1.set(Calendar.MINUTE, 0);
        cal1.set(Calendar.SECOND, 0);

        Date firstDate = cal1.getTime();
        System.out.println(format.format(firstDate));
//        LocalDate endTime = cal.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

        Calendar cal2 = Calendar.getInstance();
        cal2.set(Calendar.DAY_OF_MONTH, cal2.getActualMaximum(Calendar.DAY_OF_MONTH));
        cal1.set(Calendar.HOUR_OF_DAY, 23);
        cal1.set(Calendar.MINUTE, 59);
        cal1.set(Calendar.SECOND, 59);
        Date lastDate = cal2.getTime();
        System.out.println(format.format(firstDate));
//        LocalDate startTime = cal.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();


        TimeAO timeAO = new TimeAO();
        timeAO.setStartTimelingdian(format.format(firstDate));
        timeAO.setEndTimezhongdian(format.format(lastDate));
        return timeAO;
    }
}
